package com.mall.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.db.api.SmsCouponApi;
import com.mall.db.api.SmsCouponProductCategoryRelationApi;
import com.mall.db.api.SmsCouponProductRelationApi;
import com.mall.dto.CouponCreateDto;
import com.mall.exception.ConsumerException;
import com.mall.pageResult.PageResult;
import com.mall.pojo.SmsCoupon;
import com.mall.pojo.SmsCouponProductCategoryRelation;
import com.mall.pojo.SmsCouponProductRelation;
import com.mall.vo.CouponVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CouponService {

    @DubboReference
    private SmsCouponApi couponApi;

    @DubboReference
    private SmsCouponProductRelationApi couponProductRelationApi;

    @DubboReference
    private SmsCouponProductCategoryRelationApi couponProductCategoryRelationApi;

    /**
     * 根据优惠券名称和类型分页获取优惠券列表
     *
     * @param pageNum
     * @param pageSize
     * @param name
     * @param type
     * @return
     */
    public PageResult<SmsCoupon> list(Integer pageNum, Integer pageSize, String name, Integer type) {
        //查询
        Page<SmsCoupon> page = couponApi.list(pageNum, pageSize, name, type);
        //组装返回结果数据
        PageResult<SmsCoupon> result = new PageResult<>();
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setList(page.getRecords());
        result.setTotal(Convert.toInt(page.getTotal()));
        result.setTotalPage(Convert.toInt(page.getPages()));
        return result;
    }

    /**
     * 添加优惠券
     *
     * @param couponParam
     * @return
     */
    //@Transactional
    public Integer create(CouponCreateDto couponParam) {
        //日期严谨性判断,优惠券发放时间早于有效期开始时间，有效期开始时间早于结束时间
        Date enableTime = couponParam.getEnableTime();
        Date startTime = couponParam.getStartTime();
        Date endTime = couponParam.getEndTime();
        if (startTime.getTime() - enableTime.getTime() < 0 || endTime.getTime() - startTime.getTime() <= 0) {
            throw new ConsumerException("优惠券领取日期和有效期设置错误");
        }
        //数据拆分，分别添加到不同的表中，同时成功或失败（事务）
        SmsCoupon coupon = new SmsCoupon();
        BeanUtils.copyProperties(couponParam, coupon);
        coupon.setCount(coupon.getPublishCount()); //设置剩余可领取数量
        coupon.setUseCount(0); //设置已使用数量
        coupon.setReceiveCount(0); //设置领取数量
        coupon.setCode("123");
        coupon.setMemberLevel(0);
        Long id = couponApi.addIntoCoupon(coupon);

        List<SmsCouponProductCategoryRelation> productCategoryRelationList = couponParam.getProductCategoryRelationList();
        if (CollUtil.isNotEmpty(productCategoryRelationList)) {
            //不为空将数据添加到商品分类与优惠券关系表中
            productCategoryRelationList = productCategoryRelationList.stream().map(relation -> {
                //设置优惠券id
                relation.setCouponId(id);
                return relation;
            }).collect(Collectors.toList());
        }
        couponProductCategoryRelationApi.addIntoProductCategoryRelation(productCategoryRelationList);

        List<SmsCouponProductRelation> productRelationList = couponParam.getProductRelationList();
        if (CollUtil.isNotEmpty(productRelationList)) {
            //不为空将数据添加到商品与优惠券关系表中
            productRelationList = productRelationList.stream().map(relation -> {
                //设置优惠券id
                relation.setCouponId(id);
                return relation;
            }).collect(Collectors.toList());
        }
        couponProductRelationApi.addIntoProductRelation(productRelationList);

        return 1;
    }

    /**
     * 删除优惠券
     *
     * @param id
     * @return
     */
    public Integer delete(Integer id) {
        //删除优惠券
        Integer count = couponApi.deleteById(id);
        //删除商品分类与优惠券关系
        couponProductCategoryRelationApi.deleteByCouponId(id);
        //删除商品与优惠券关系
        couponProductRelationApi.deleteByCouponId(id);
        return count;
    }

    /**
     * 获取单个优惠券的详细信息
     *
     * @param id
     * @return
     */
    public CouponVo couponMsg(Integer id) {
        //组装返回结果数据
        CouponVo vo = new CouponVo();
        //查询优惠券
        SmsCoupon coupon = couponApi.findById(id);
        BeanUtils.copyProperties(coupon, vo);
        //查询商品分类与优惠券关系
        List<SmsCouponProductCategoryRelation> couponProductCategoryRelations = couponProductCategoryRelationApi.findByCouponId(id);
        vo.setProductCategoryRelationList(couponProductCategoryRelations);
        //查询商品与优惠券关系
        List<SmsCouponProductRelation> couponProductRelations = couponProductRelationApi.findByCouponId(id);
        vo.setProductRelationList(couponProductRelations);
        return vo;
    }

    /**
     * 修改优惠券
     *
     * @param id
     * @param couponParam
     * @return
     */
    public Integer update(Integer id, CouponCreateDto couponParam) {
        //日期严谨性判断,优惠券发放时间早于有效期开始时间，有效期开始时间早于结束时间
        Date enableTime = couponParam.getEnableTime();
        Date startTime = couponParam.getStartTime();
        Date endTime = couponParam.getEndTime();
        if (startTime.getTime() - enableTime.getTime() < 0 || endTime.getTime() - startTime.getTime() <= 0) {
            throw new ConsumerException("优惠券领取日期和有效期设置错误");
        }
        //数据拆分，分别修改到不同的表中，同时成功或失败（事务）
        SmsCoupon coupon = new SmsCoupon();
        BeanUtils.copyProperties(couponParam, coupon);

        Integer count = couponApi.updateIntoCoupon(coupon);

        List<SmsCouponProductCategoryRelation> productCategoryRelationList = couponParam.getProductCategoryRelationList();
        if (CollUtil.isNotEmpty(productCategoryRelationList)) {
            //不为空将数据修改到商品分类与优惠券关系表中
            List<SmsCouponProductCategoryRelation> categoryUpdateList = new ArrayList<>();
            List<SmsCouponProductCategoryRelation> categoryAddList = new ArrayList<>();
            for (SmsCouponProductCategoryRelation relation : productCategoryRelationList) {
                if (ObjectUtil.isNotNull(relation.getId())){
                    categoryUpdateList.add(relation);
                }else {
                    relation.setCouponId(Convert.toLong(id));
                    categoryAddList.add(relation);
                }
            }
            couponProductCategoryRelationApi.updateIntoProductCategoryRelation(categoryUpdateList);
            couponProductCategoryRelationApi.addIntoProductCategoryRelation(categoryAddList);
        }

        List<SmsCouponProductRelation> productRelationList = couponParam.getProductRelationList();
        if (CollUtil.isNotEmpty(productRelationList)) {
            List<SmsCouponProductRelation> productAddList = new ArrayList<>();
            List<SmsCouponProductRelation> productUpdateList = new ArrayList<>();
            for (SmsCouponProductRelation relation : productRelationList) {
                if (ObjectUtil.isNotNull(relation.getId())){
                    productUpdateList.add(relation);
                }else {
                    relation.setCouponId(Convert.toLong(id));
                    productAddList.add(relation);
                }
            }
            couponProductRelationApi.updateIntoProductRelation(productUpdateList);
            couponProductRelationApi.addIntoProductRelation(productAddList);
        }

        return count;
    }
}
